﻿using ASmile.Extend;
using ASmile.ORM.CodeBuilder.Builder;
using System;
using System.Collections.Generic;
using System.IO;
using System.Windows.Forms;
using System.Xml.Serialization;

namespace ASmile.ORM.CodeBuilder
{
    public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();
        }

        IBuilder CurrBuilder { get; set; }

        List<M_Table> CurrTables { set; get; }

        List<M_View> CurrViews { set; get; }

        List<M_Proc> CurrProcs { set; get; }

        List<M_Config> BuilderConfigs { get; set; }

        void ShowMessage(string msg)
        {
            MessageBox.Show(msg);
        }

        void CreateCode()
        {
            if (coBoxDBObjType.SelectedIndex == 0)
            {
                M_Table selModel = dgvTable.GetSelectedClassData<M_Table>();

                if (selModel == null)
                {
                    selModel = new M_Table();
                }
                selModel.TableName = txtDBObjName.Text;
                txtCode.Text = CurrBuilder.GetTableCode(selModel);
                //ShowMessage($"生成表代码 {selModel.TableName} 完成");
            }
            else if (coBoxDBObjType.SelectedIndex == 1)
            {
                M_View selModel;
                if (tabControl1.SelectedIndex == 0)
                {
                    selModel = dgvTable.GetSelectedClassData<M_View>();
                }
                else
                {
                    selModel = dgvView.GetSelectedClassData<M_View>();
                }

                if (selModel == null)
                {
                    selModel = new M_View();
                }
                selModel.TableName = txtDBObjName.Text;
                txtCode.Text = CurrBuilder.GetViewCode(selModel);
                //ShowMessage($"生成视图代码 {selModel.TableName} 完成");
            }
            else if (coBoxDBObjType.SelectedIndex == 2)
            {
                var selModel = dgvProc.GetSelectedClassData<M_Proc>();
                if (selModel == null)
                {
                    selModel = new M_Proc();
                }
                selModel.ProcName = txtDBObjName.Text;
                txtCode.Text = CurrBuilder.GetProcCode(selModel);
                //ShowMessage($"生成存储过程代码 {selModel.ProcName} 完成");
            }
            else
            {
                MessageBox.Show("错误的选项卡");
            }
            //txtCode.Foncs();
            txtCode.ScrollToCaret();
        }

        /// <summary>
        /// 保存单个类文件
        /// </summary>
        void SaveCodeFileDialog(string dbObjName, string fileContent)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "*.cs|*.cs";
            sfd.FileName = dbObjName + ".cs";
            sfd.InitialDirectory = txtSavePath.Text;
            if (sfd.ShowDialog() == DialogResult.OK)
            {
                SaveCodeToFile(fileContent, sfd.FileName);
                ShowMessage($"保存 {txtDBObjName.Text} 完成");
            }
        }
        /// <summary>
        /// 保存代码到文件
        /// </summary>
        void SaveCodeToFile(string codeStr, string fileName)
        {
            if (string.IsNullOrEmpty(codeStr))
            {
                MessageBox.Show("代码为空!", "保存提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                return;
            }
            using (FileStream fs = new FileStream(fileName, FileMode.Create))
            {
                using (StreamWriter sw = new StreamWriter(fs))
                {
                    sw.Write(codeStr);
                }
            }
        }

        void SetConfigFile()
        {
            if (coBoxCaption.Items.Count == 0)
            {
                ShowMessage("配置列表为空");
                return;
            }
            var conf = coBoxCaption.SelectedItem as M_Config;
            txtDBType.Text = conf.DBType;
            txtNameSpace.Text = conf.NameSpace;
            txtSavePath.Text = conf.SavePath;
            txtConnStr.Text = conf.ConnStr;
        }

        private void FrmMain_Load(object sender, EventArgs e)
        {
            var serializer = new XmlSerializer(typeof(BuilderConfigCollection));
            var confFileName = Config.ConfigFileName;
            // 从文件反序列化为对象
            using (var reader = new StreamReader(confFileName))
            {
                var bookCollection = (BuilderConfigCollection)serializer.Deserialize(reader);
                BuilderConfigs = bookCollection.BuilderConfigs;
                if (BuilderConfigs == null)
                {
                    ShowMessage("配置文件为空");
                    return;
                }
            }
            coBoxCaption.ValueMember = "Caption";
            coBoxCaption.DisplayMember = "Caption";
            coBoxCaption.DataSource = BuilderConfigs;
            SetConfigFile();
            coBoxCaption.SelectedIndexChanged += CoBoxCaption_SelectedIndexChanged;
        }

        private void CoBoxCaption_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetConfigFile();
        }

        private void tsBtnRefeshDBObj_Click(object sender, EventArgs e)
        {
            CurrBuilder = BuilderFactory.Create(new M_Config
            {
                ConnStr = txtConnStr.Text,
                DBType = txtDBType.Text,
                NameSpace = txtNameSpace.Text,
            });

            if (tabControl1.SelectedTab == tabPageTable)
            {
                CurrTables = CurrBuilder.GetTables();
                dgvTable.DataSource = CurrTables;
            }
            else if (tabControl1.SelectedTab == tabPageView)
            {
                CurrViews = CurrBuilder.GetViews();
                dgvView.DataSource = CurrViews;
            }
            else if (tabControl1.SelectedTab == tabPageProc)
            {
                CurrProcs = CurrBuilder.GetProcs();
                dgvProc.DataSource = CurrProcs;
            }
            else
            {
                MessageBox.Show("错误的选项卡");
            }
        }

        private void tsBtnSearchDB_Click(object sender, EventArgs e)
        {
            if (CurrBuilder == null)
            {
                ShowMessage("未选中配置");
                return;
            }
            if (tabControl1.SelectedTab == tabPageTable)
            {
                if (CurrTables == null)
                {
                    ShowMessage("表对象为空，请先刷新");
                    return;
                }
                string serVal = tsTxtSearchDBObj.Text;
                if (serVal.IsEmpty())
                {
                    dgvTable.DataSource = CurrTables;
                    return;
                }
                var rList = CurrTables.FindAll(s => s.TableName.ContainsLike(serVal) || s.TableRemark.ContainsLike(serVal));
                dgvTable.DataSource = rList;
            }
            else if (tabControl1.SelectedTab == tabPageView)
            {
                if (CurrViews == null)
                {
                    ShowMessage("视图对象为空，请先刷新");
                    return;
                }
                string serVal = tsTxtSearchDBObj.Text;
                if (serVal.IsEmpty())
                {
                    dgvView.DataSource = CurrViews;
                    return;
                }
                var rList = CurrViews.FindAll(s => s.TableName.ContainsLike(serVal) || s.TableRemark.ContainsLike(serVal));
                dgvView.DataSource = rList;
            }
            else if (tabControl1.SelectedTab == tabPageProc)
            {
                if (CurrProcs == null)
                {
                    ShowMessage("视图对象为空，请先刷新");
                    return;
                }
                string serVal = tsTxtSearchDBObj.Text;
                if (serVal.IsEmpty())
                {
                    dgvProc.DataSource = CurrProcs;
                    return;
                }
                var rList = CurrProcs.FindAll(s => s.ProcName.ContainsLike(serVal) || s.ProcCaption.ContainsLike(serVal));
                dgvProc.DataSource = rList;
            }
            else
            {
                MessageBox.Show("错误的选项卡");
            }
        }

        private void tsTxtSearchDBObj_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter)
            {
                tsBtnSearchDB_Click(sender, e);
            }
        }

        private void tsBtnGenerateCode_Click(object sender, EventArgs e)
        {
            if (CurrBuilder == null)
            {
                ShowMessage("未创建Builder, 请选择配置");
                return;
            }
            CreateCode();
        }

        private void tsBtnSaveCode_Click(object sender, EventArgs e)
        {
            SaveCodeFileDialog(txtDBObjName.Text, txtCode.Text);
        }

        private void tsBtnSetClipBoard_Click(object sender, EventArgs e)
        {
            Clipboard.SetText(txtCode.Text);
            ShowMessage("保存到剪切板完成");
        }

        private void dgvTable_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            coBoxDBObjType.SelectedIndex = 0;
            var selModel = dgvTable.GetSelectedClassData<M_Table>(e.RowIndex);
            txtDBObjName.Text = selModel.TableName;
        }

        private void dgvView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            coBoxDBObjType.SelectedIndex = 1;
            var selModel = dgvView.GetSelectedClassData<M_View>(e.RowIndex);
            txtDBObjName.Text = selModel.TableName;
        }

        private void dgvProc_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            coBoxDBObjType.SelectedIndex = 2;
            var selModel = dgvProc.GetSelectedClassData<M_Proc>(e.RowIndex);
            txtDBObjName.Text = selModel.ProcName;
        }
    }
}